package com.example.demo.util;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class DiskDirUtil {
    private static final char[] CHARS = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

    /**
     * 根据当前目录ID和父目录路径，生成完成路径
     * @param dirId
     * @param parentPath
     * @return
     */
    public static String id2Path(int dirId, String parentPath) {
        if (dirId < 1) {//编号从1开始
            return "";
        }
        StringBuilder builder = new StringBuilder();
        int i = dirId%10;
        builder.append((dirId - 1)%10);
        int nextVal = (dirId - 1) / 10;
        while (nextVal > 0) {
            builder.append(CHARS[(nextVal - 1) % 52]);
            nextVal = (nextVal - 1) / 52;
        }
        if(StringUtils.isBlank(parentPath)) {
            return builder.reverse().toString();
        }
        return parentPath + builder.reverse().toString();
    }

    /**
     * 完整路径转目录ID列表，当前目录为最后一个
     * @param path
     * @return
     * c >= 48 && c <= 57 → 数字字符（'0'到'9'的 ASCII 值为 48~57）。
     * c >= 97 && c <= 122 → 小写字母（'a'到'z'的 ASCII 值为 97~122）。
     * c >= 65 && c <= 90 → 大写字母（'A'到'Z'的 ASCII 值为 65~90）
     */
    public static List<Integer> path2Ids(String path) {
        if(StringUtils.isBlank(path)) {
            return Collections.singletonList(0);
        }
        List<Integer> ret = new ArrayList<>();
        int currVal = 0;
        int factor = 1;
        for(int i = path.length() - 1; i >= 0; i--){ //先倒序
            char c = path.charAt(i);
            if (c >= 48 && c <= 57){//是数字，为边界
                if(currVal > 0) {//先返回上一个目录ID
                    ret.add(currVal);
                    currVal = 0;//重置
                    factor = 1;//重置
                }
                currVal += (c - 48 + 1);
                factor = factor * 10;
            } else if (c >= 97 && c <= 122) { //是小写字符
                currVal += (c - 97 + 1) * factor;
                factor = factor * 52;
            } else if (c >= 65 && c <= 90) { //是大写字符
                currVal += (c - 65 + 1 + 26) * factor;
                factor = factor * 52;
            }
        }
        if(currVal > 0) {//处理上一个目录ID
            ret.add(currVal);
        }
        Collections.reverse(ret);
        return ret;
    }

    public static void main(String[] args) {
        System.out.println(path2Ids("0178a6"));
    }

    /**
     * 根据代码逻辑和路径 "0178a6" 的处理，父路径的完整推导过程及结果如下：
     *
     * 1. 路径解析与目录ID列表生成
     * 路径字符串: "0178a6"
     *
     * 倒序处理字符: 6 → a → 8 → 7 → 1 → 0
     *
     * 转换规则：
     *
     * 数字字符：值 = 字符值 - 48 + 1（如 '6' → 7）。
     *
     * 小写字母：值 = (字母序数 + 1) × 当前权值（如 'a' → 1 × 10 = 10）。
     *
     * 权值因子：每遇到字母时乘以 52，数字时乘以 10。
     *
     * 目录ID列表生成过程：
     *
     * 字符	类型	值计算	当前段值（currVal）	权值（factor）	操作
     * 6	数字	6-48+1 = 7	7	10	开始新段
     * a	小写	(97-97+1) × 10 = 10	7+10=17	520	累积
     * 8	数字	8-48+1 = 9	9	10	结束前段（17入列）
     * 7	数字	7-48+1 = 8	8	10	结束前段（9入列）
     * 1	数字	1-48+1 = 2	2	10	结束前段（8入列）
     * 0	数字	0-48+1 = 1	1	10	结束前段（2入列）
     * 最终目录ID列表：反转后为 [1, 2, 8, 9, 17]，表示路径层级。
     *
     * 2. 父路径推导
     * 父路径是当前路径的上一层目录，即去掉最后一个目录ID后的列表：
     *
     * 当前目录ID列表: [1, 2, 8, 9, 17]
     *
     * 父目录ID列表: [1, 2, 8, 9]
     *
     * 根据目录ID与字符的对应关系：
     *
     * ID → 字符映射：
     *
     * 1 → '0'
     *
     * 2 → '1'
     *
     * 8 → '7'
     *
     * 9 → '8'
     *
     * 父路径字符串: "0178"
     *
     * 3. 完整父路径列表
     * 从当前路径逐级向上推导所有父路径：
     *
     * 层级	目录ID列表	对应路径字符串
     * 当前路径	[1, 2, 8, 9, 17]	"0178a6"
     * 直接父路径	[1, 2, 8, 9]	"0178"
     * 祖父路径	[1, 2, 8]	"017"
     * 曾祖父路径	[1, 2]	"01"
     * 根目录	[0]	空字符串
     * 4. 关键逻辑验证
     * 数字作为分段符：路径中每个数字字符标识一个新段的开始（倒序处理时）。
     *
     * 字母参与权值计算：字母会累积到当前段的值中，但不会触发分段。
     *
     * 权值因子规则：字母按 52 进制累积，数字按 10 进制累积。
     *
     * 结论
     * 当前路径 "0178a6" 的完整父路径依次为：
     *
     * 直接父路径: "0178"
     *
     * 祖父路径: "017"
     *
     * 曾祖父路径: "01"
     *
     * 根目录: 空字符串（对应 [0]）。
     */
}
